<?php
/**
 * Created by PhpStorm.
 * User: zhengze
 * Date: 2019/7/1
 * Time: 18:29
 */

namespace app\admin\service;

use app\common\model\Admin;
use app\common\model\AdminAccess;
use app\admin\validate\AdminValidate;
use common\exception\AdminException;
use common\exception\ExceptionEmun;
use common\exception\RecordException;
use common\helper\ArrayHelper;
use common\service\BaseService;
use common\Token\Token;
use common\traits\InstanceTrait;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\DbException;

/**
 * Class AdminService
 * @package app\api\service
 */
class AdminService extends BaseService
{
    use InstanceTrait;


    /**
     * 登录
     * @param string $username 账号
     * @param string $password 密码
     * @param bool $isRemember 是否记住密码
     * @param bool $type 是否重复登录
     * @return array|bool
     * @throws \common\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function login($username, $password, $isRemember = false, $type = false)
    {
        $Admin = Admin::instance();
        $userInfo = AdminValidate::instance()->getTempAdmin();
        if ($userInfo['status'] === 0) {
            ExceptionEmun::throwException(AdminException::LOCKED);
            return false;
        }
        // 获取菜单和权限
        $admin_id = $userInfo[$Admin->getPk()];
        $data = $this->getMore($admin_id);
        $data['userInfo']->hidden(['groups']);
        if ($isRemember || $type) {
            $secret['username'] = $username;
            $secret['password'] = $password;
            $data['rememberKey'] = encrypt($secret);
        }
        $jwt = $this->createJwt($userInfo);
        $data = array_merge($data, $jwt);
        return $data;
    }

    /**
     * 根据uid返回用户信息(权限，菜单，用户信息),
     * 用于获取正在登录用户和已经登录用户的信息
     * @param $uid
     * @return bool
     * @throws \common\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getMore($uid)
    {
        $Admin = Admin::instance();
        $userInfo = $Admin->getById($uid);
        $userInfo->hidden(['password']);
        $dataList = $Admin->getMenuList($userInfo);
        if (empty($dataList['menusList'])) {
            ExceptionEmun::throwException(AdminException::NO_RIGHT);
            return false;
        }
        $data['userInfo'] = $userInfo;
        $data['menusList'] = $dataList['menusList'];
        return $data;
    }

    /**
     * JWT生成token
     * @param $userinfo ,可以传admin_id
     * @return array
     */
    public function createJwt($userinfo)
    {
        if (!empty($userinfo) && is_int($userinfo)) {
            $userinfo = Admin::instance()->getByID($userinfo);
        }
        $userinfo['model'] = Admin::class;
        $Token = Token::instance();
        $token = $Token->generateToken($userinfo);
        return ['token' => $token, 'expire' => $Token->getPayload()->exp_time];
    }

    /**
     * [getDataList 列表]
     * @AuthorHTL
     * @DateTime  2017-02-10T22:19:57+0800
     * @param $keywords
     * @param $page
     * @param $limit
     * @return mixed [array]                             [description]
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     * @noinspection UnsupportedStringOffsetOperationsInspection
     */
    public function getDataList($param)
    {
        $Admin = Admin::instance();
        $where = $Admin->getBaseWhere($param);
//      除去超级管理员s
//      $where[] = ['user.'.$Admin->getPk(), '<>', '1'];
        $dataCount = $Admin->alias('user')
                           ->where($where)
                           ->count('*');
        $param['page'] = !empty($param['page']) ? $param['page'] : 1;
        $param['limit'] = !empty($param['limit']) ? $param['limit'] : 15;
        $list = $Admin
            ->where($where)
            ->alias('user')
            ->page($param['page'], $param['limit'])
            ->field($Admin->baseField)
            ->select();
        $list->hidden(['password']);
        if (false === $list->isEmpty()) {
            $list->load('post,structure');
        }

        $data['list'] = $list;
        $data['dataCount'] = $dataCount;

        return $data;
    }

    /**
     * @param $param
     */
    public function read($admin_id)
    {
        $Admin = Admin::instance();
        $admin = $Admin->getByID($admin_id);
        if (empty($admin)) {
            ExceptionEmun::throwException(AdminException::NO_EXIST);
        }
        $admin->hidden(['password']);
        return $admin;
    }

    /**
     * AdminAccess中间表写入
     * @param $group_id
     * @param $admin_id
     * @param $menus
     */
    protected function insertAccessRelation($admin_id, $groups)
    {

        $user_info = Token::instance()->getUserInfo();
        $creater_id = $user_info[$user_info->getPk()];
        $groups = ArrayHelper::to_array($groups);
        $data = [
            'create_time' => $_SERVER['REQUEST_TIME'],
            'updater_id' => $_SERVER['REQUEST_TIME'],
            'creater_id' => $creater_id,
            'updater_id' => $creater_id,
            'admin_id' => $admin_id
        ];
        $insertAllDate = [];
        foreach ($groups as $key => $value) {
            $insertAllDate[$key] = $data;
            $insertAllDate[$key]['group_id'] = $value;
        }
        Db::table(AdminAccess::instance()->getTable())->insertAll($insertAllDate);
    }

    /**
     * 创建用户
     * @param array $param [description]
     */
    public function createData($param)
    {
        // 验证
        Admin::instance()->startTrans();
        $param['phone'] = 0;
        $param['password'] = encrypt_password($param['password']);
        $Admin = Admin::create($param);
//        太慢,废除
//        $Admin->groups()->saveAll($param['groups']);
        $this->insertAccessRelation($Admin['admin_id'], $param['groups']);
        Admin::instance()->commit();
        return true;
    }


    /**
     * 通过id修改用户
     * @param array $param [description]
     */
    public function updateByID($param)
    {
        $Admin = Admin::instance();
        $id = $param[$Admin->getPk()] ?? $param['id'];
        $Admin->startTrans();
        // 只有超级管理员能操作超级管理员
        if (1 === (int)$id && 1 !== (int)Token::instance()->getUserInfo()[$Admin->pk]) {
            ExceptionEmun::throwException(AdminException::$update_admin);
        }
        $admin = Admin::field($Admin->baseField)->where('admin_id', '=', $id)->find();
        if (!$admin) {
            ExceptionEmun::throwException(AdminException::NO_EXIST);
        }
        $admin->groups()->detach();
//        太慢,废除
//        $admin->groups()->saveAll($param['groups']);
        $this->insertAccessRelation($id, $param['groups']);
        //填了密码就加密,不填就不该密码
        if (!empty($param['password'])) {
            $param['password'] = encrypt_password($param['password']);
        } else {
            unset($param['password']);
        }
        $admin->save($param);
        $Admin->commit();
        return true;

    }
}